@marko/translator-default
Version:
Translates Marko templates to the default Marko runtime.
186 lines (160 loc) • 6.04 kB
JavaScript
;var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");exports.__esModule = true;exports.default = _default;var _babelUtils = require("@marko/babel-utils");
var _compiler = require("@marko/compiler");
var FLAGS = _interopRequireWildcard(require("../../util/runtime-flags"));
var _vdomOutWrite = _interopRequireDefault(require("../../util/vdom-out-write"));
var _withPreviousLocation = _interopRequireDefault(require("../../util/with-previous-location"));
var _attributes = _interopRequireDefault(require("./attributes"));function _getRequireWildcardCache(e) {if ("function" != typeof WeakMap) return null;var r = new WeakMap(),t = new WeakMap();return (_getRequireWildcardCache = function (e) {return e ? t : r;})(e);}function _interopRequireWildcard(e, r) {if (!r && e && e.__esModule) return e;if (null === e || "object" != typeof e && "function" != typeof e) return { default: e };var t = _getRequireWildcardCache(r);if (t && t.has(e)) return t.get(e);var n = { __proto__: null },a = Object.defineProperty && Object.getOwnPropertyDescriptor;for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) {var i = a ? Object.getOwnPropertyDescriptor(e, u) : null;i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u];}return n.default = e, t && t.set(e, n), n;}
const SIMPLE_ATTRS = ["id", "class", "style"];
/**
* Translates the html streaming version of a standard html element.
*/
function _default(path, isNullable) {
const { node } = path;
const {
name,
key,
body: { body }
} = node;
const isEmpty = !body.length;
const writeArgs = tagArguments(path, false);
let writeStartNode = (0, _withPreviousLocation.default)(
(0, _vdomOutWrite.default)(isEmpty ? "e" : "be", ...writeArgs),
node.name
);
if (isNullable) {
writeStartNode = _compiler.types.ifStatement(name, writeStartNode);
if (!isEmpty) {
writeStartNode.alternate = _compiler.types.expressionStatement(
_compiler.types.callExpression(
_compiler.types.memberExpression(_compiler.types.identifier("out"), _compiler.types.identifier("bf")),
[
(0, _babelUtils.normalizeTemplateString)`f_${key}`,
path.hub.file._componentInstanceIdentifier]
)
);
}
}
if (isEmpty) {
path.replaceWith(writeStartNode);
return;
}
let writeEndNode = (0, _vdomOutWrite.default)("ee");
if (isNullable) {
writeEndNode = _compiler.types.ifStatement(
name,
writeEndNode,
_compiler.types.expressionStatement(
_compiler.types.callExpression(
_compiler.types.memberExpression(_compiler.types.identifier("out"), _compiler.types.identifier("ef")),
[]
)
)
);
}
let needsBlock;
for (const childNode of body) {
if (_compiler.types.isVariableDeclaration(childNode)) {
if (childNode.kind === "const" || childNode.kind === "let") {
needsBlock = true;
break;
}
}
}
path.replaceWithMultiple(
[writeStartNode].
concat(needsBlock ? _compiler.types.blockStatement(body) : body).
concat(writeEndNode)
);
}
function isPropertyName({ key }, names) {
if (_compiler.types.isStringLiteral(key)) {
return names.includes(key.value);
} else if (_compiler.types.isIdentifier(key)) {
return names.includes(key.name);
}
}
function tagArguments(path) {
const {
hub: { file },
node
} = path;
const {
name,
key,
body: { body },
handlers
} = node;
const tagProperties = path.node.extra && path.node.extra.properties || [];
const attrsObj = (0, _attributes.default)(path, path.get("attributes"));
let runtimeFlags = 0;
if (!_compiler.types.isNullLiteral(attrsObj) && !_compiler.types.isObjectExpression(attrsObj)) {
runtimeFlags |= FLAGS.SPREAD_ATTRS;
}
const writeArgs = [
name,
attrsObj,
key,
file._componentInstanceIdentifier,
body.length ? _compiler.types.nullLiteral() : _compiler.types.numericLiteral(0)];
if (node.preserveAttrs) {
tagProperties.push(
_compiler.types.objectProperty(
_compiler.types.identifier("pa"),
_compiler.types.objectExpression(
node.preserveAttrs.map((name) =>
_compiler.types.objectProperty(
_compiler.types.isValidIdentifier(name) ?
_compiler.types.identifier(name) :
_compiler.types.stringLiteral(name),
_compiler.types.numericLiteral(1)
)
)
)
)
);
}
if (handlers) {
Object.entries(handlers).forEach(
([eventName, { arguments: args, once }]) => {
const delegateArgs = [_compiler.types.stringLiteral(eventName), args[0]];
// TODO: look into only sending this if once is true.
delegateArgs.push(_compiler.types.booleanLiteral(once));
if (args.length > 1) {
delegateArgs.push(_compiler.types.arrayExpression(args.slice(1)));
}
// TODO: why do we output eventName twice.
tagProperties.push(
_compiler.types.objectProperty(
_compiler.types.stringLiteral(`on${eventName}`),
_compiler.types.callExpression(
_compiler.types.memberExpression(
file._componentDefIdentifier,
_compiler.types.identifier("d")
),
delegateArgs
)
)
);
}
);
}
if (
_compiler.types.isObjectExpression(attrsObj) &&
attrsObj.properties.every((n) => isPropertyName(n, SIMPLE_ATTRS)) &&
!node.preserveAttrs)
{
runtimeFlags |= FLAGS.HAS_SIMPLE_ATTRS;
}
const tagDef = (0, _babelUtils.getTagDef)(path);
if (tagDef) {
const { htmlType } = tagDef;
if (htmlType === "custom-element") {
runtimeFlags |= FLAGS.IS_CUSTOM_ELEMENT;
}
}
writeArgs.push(_compiler.types.numericLiteral(runtimeFlags));
if (tagProperties.length) {
writeArgs.push(_compiler.types.objectExpression(tagProperties));
}
return writeArgs;
}